package pl.register.android.activities.correlation.logic;

import pl.register.android.group.StudentsGroup;
import pl.register.android.lesson.LessonProgram;
import pl.register.android.lesson.TagLesson;
import pl.register.android.program.Program;
import pl.register.android.student.Student;
import pl.register.android.year.Year;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author Mateusz Strzelecki
 * @since 2013-05-11
 */
public class Correlation {

    private Year year;

    private List<StudentsGroup> groups;

    private Map<TagLesson, Program> programMap;

    private Map<Long, StudentsGroup> groupMap;

    private Map<Long, Integer> studentOrderMap;

    private Program program;

    public Correlation(Year year, List<StudentsGroup> groups, Map<TagLesson, Program> programMap) {
        studentOrderMap = new HashMap<Long, Integer>();
        program = new Program();
        this.year = year;
        this.groups = groups;
        this.programMap = programMap;
        this.groupMap = createGroupMap(groups);
    }

    private Map<Long, StudentsGroup> createGroupMap(List<StudentsGroup> groups) {
        Map<Long, StudentsGroup> groupMap = new HashMap<Long, StudentsGroup>();
        for (StudentsGroup group : groups) {
            List<Student> students = group.getStudents();
            reorderStudents(students);
            for (Student student : students) {
                groupMap.put(student.getId(), group);
            }
        }
        return groupMap;
    }

    private void reorderStudents(List<Student> students) {
        int order = 1;
        for (Student student : students) {
            studentOrderMap.put(student.getId(), order);
            order++;
        }
    }

    public Year getYear() {
        return year;
    }

    public List<StudentsGroup> getGroups() {
        return groups;
    }

    public List<Student> getAllStudents() {
        List<Student> allStudents = new ArrayList<Student>();
        for (StudentsGroup group : groups) {
            allStudents.addAll(group.getStudents());
        }
        return allStudents;
    }

    public void addStudentTo(Student student, StudentsGroup group) {
        for (StudentsGroup studentGroup : groups) {
            if (studentGroup.getType().equals(group.getType())) {
                studentGroup.addStudent(student);
                groupMap.put(student.getId(), studentGroup);
                reorderStudents(studentGroup.getStudents());
                return;
            }
        }
    }

    public void removeStudentFrom(Student student, StudentsGroup group) {
        for (StudentsGroup studentGroup : groups) {
            if (studentGroup.getType().equals(group.getType())) {
                studentGroup.removeStudent(student);
                reorderStudents(studentGroup.getStudents());
                return;
            }
        }
    }

    public StudentsGroup getStudentGroup(Student student) {
        return groupMap.get(student.getId());
    }

    public Program getProgramBy(TagLesson tag) {
        return programMap.get(tag);
    }

    public Program getProgram() {
        return program;
    }

    public void setProgram(TagLesson tag) {
        program = getProgramBy(tag);
        for (StudentsGroup group : groups) {
            group.setProgram(program);
        }
    }

    public void addLessonProgram(LessonProgram lessonProgram) {
        program.addLessonProgram(lessonProgram);
        for (StudentsGroup group : groups) {
            group.setProgram(program);
        }
    }

    public void removeFromDisplayLessonProgram(LessonProgram lessonProgram) {
        program.removeLessonProgram(lessonProgram);
        for (StudentsGroup group : groups) {
            group.setProgram(program);
        }
    }

    public void removeLessonProgram(LessonProgram toRemove) {
        for (Program program : programMap.values()) {
            for (LessonProgram lessonProgram : program.getLessons()) {
                if (lessonProgram.getId().equals(toRemove.getId())) {
                    program.removeLessonProgram(lessonProgram);
                    return;
                }
            }
        }
    }

    public String getYearGroupName() {
        return year.getSubName();
    }


    public Integer getStudentOrder(Student student) {
        return studentOrderMap.get(student.getId());
    }
}
